package com.ohos.connect.devicecloud.app.modular.projectdevice.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ohos.connect.devicecloud.app.modular.project.model.entity.Project;
import com.ohos.connect.devicecloud.app.modular.project.service.ProjectService;
import com.ohos.connect.devicecloud.app.modular.projectdevice.model.dto.ProjectDeviceDeleteDTO;
import com.ohos.connect.devicecloud.app.modular.projectdevice.model.vo.ProjectDeviceInfoVO;
import com.ohos.connect.devicecloud.app.modular.projectdevice.model.vo.ProjectDeviceListVO;
import com.ohos.connect.devicecloud.app.modular.projectuser.model.entity.ProjectUser;
import com.ohos.connect.devicecloud.app.modular.projectuser.service.ProjectUserService;
import com.ohos.connect.devicecloud.iot.api.DeviceApi;
import com.ohos.connect.devicecloud.iot.model.vo.DeviceInfoVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ohos.connect.devicecloud.common.exception.CommonException;
import com.ohos.connect.devicecloud.app.modular.projectdevice.model.entity.ProjectDevice;
import com.ohos.connect.devicecloud.app.modular.projectdevice.mapper.ProjectDeviceMapper;
import com.ohos.connect.devicecloud.app.modular.projectdevice.model.dto.ProjectDeviceAddDTO;
import com.ohos.connect.devicecloud.app.modular.projectdevice.model.param.ProjectDeviceEditParam;
import com.ohos.connect.devicecloud.app.modular.projectdevice.model.dto.ProjectDeviceSearchDTO;
import com.ohos.connect.devicecloud.app.modular.projectdevice.service.ProjectDeviceService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * APP项目设备Service接口实现类
 *
 * @author Dongtao
 * @date  2024/12/05 11:08
 **/
@Service
public class ProjectDeviceServiceImpl extends ServiceImpl<ProjectDeviceMapper, ProjectDevice> implements ProjectDeviceService {

    @Resource
    private ProjectService projectService;

    @Resource
    private ProjectUserService projectUserService;

    @Resource
    private DeviceApi deviceApi;

    @Override
    public String getProjectIdByDeviceId(String deviceId) {
        QueryWrapper<ProjectDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_id", deviceId);
        ProjectDevice projectDevice = getOne(queryWrapper);
        if (projectDevice != null) {
            return projectDevice.getProjectId();
        }

        return "";
    }

    @Transactional
    @Override
    public Boolean deleteProjectDevice(String deviceId) {
        if(ObjectUtil.isEmpty(deviceId)){
            throw new CommonException("设备id不能为空");
        }

        QueryWrapper<ProjectDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("device_id", deviceId);
        List<ProjectDevice> projectDevices = list(queryWrapper);

        return this.removeBatchByIds(projectDevices);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(ProjectDeviceAddDTO projectDeviceAddDTO) {
        String projectId = projectDeviceAddDTO.getProjectId();
        projectUserService.getProjectUserByProjectId(projectId);

        // 判断项目id是否合法
        Project project = projectService.getById(projectDeviceAddDTO.getProjectId());
        if(ObjectUtil.isEmpty(project)){
            throw new CommonException("项目不存在，项目id:"+ projectDeviceAddDTO.getProjectId());
        }
        // 校验插入的设备ID列表
        checkDeviceIdList(projectDeviceAddDTO.getDeviceIdList());

        // 获取项目下设备ID列表
        List<String> deviceIdList = getProjectDeviceIdList(projectId);
        // 没有交集返回true
        if(!Collections.disjoint(deviceIdList,projectDeviceAddDTO.getDeviceIdList())){
            List<String> repeatDeviceIdList = projectDeviceAddDTO.getDeviceIdList().stream().filter(deviceIdList::contains).collect(Collectors.toList());
            throw new CommonException("设备重复添加，设备id: "+repeatDeviceIdList);
        }

        // 构造要插入的项目设备列表
        List<ProjectDevice> insertProjectDeviceList = new ArrayList<>();
        for(String deviceId : projectDeviceAddDTO.getDeviceIdList()){
            ProjectDevice projectDevice = new ProjectDevice();
            projectDevice.setProjectId(projectId);
            projectDevice.setDeviceId(deviceId);
            insertProjectDeviceList.add(projectDevice);
        }

        // 批量插入项目设备表
        return this.saveBatch(insertProjectDeviceList);
    }

    private void checkDeviceIdList(List<String> deviceIdList){
        if(ObjectUtil.isEmpty(deviceIdList)){
            throw new CommonException("设备id不能为空");
        }

        List<DeviceInfoVO> deviceInfoVOList = deviceApi.getDeviceInfoList(deviceIdList);
        if(deviceIdList.size() != deviceInfoVOList.size()){
            throw new CommonException("存在未注册设备，数量："+(deviceIdList.size()-deviceInfoVOList.size()));
        }

    }

    // 获取项目下所有的设备id
    private List<String> getProjectDeviceIdList(String projectId){
        QueryWrapper<ProjectDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(ProjectDevice::getProjectId,projectId);
        List<ProjectDevice> projectDeviceList = this.list(queryWrapper);

        List<String> deviceIdList = new ArrayList<>();
        for(ProjectDevice projectDevice : projectDeviceList){
            if(ObjectUtil.isNotNull(projectDevice.getDeviceId())){
                deviceIdList.add(projectDevice.getDeviceId());
            }
        }
        return deviceIdList;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(ProjectDeviceEditParam projectDeviceEditParam) {
        ProjectDevice projectDevice = this.queryEntity(projectDeviceEditParam.getId());
        BeanUtil.copyProperties(projectDeviceEditParam, projectDevice);
        this.updateById(projectDevice);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean delete(ProjectDeviceDeleteDTO projectDeviceDeleteDTO) {
        String projectId = projectDeviceDeleteDTO.getProjectId();
        // 项目ID校验
        projectUserService.getProjectUserByProjectId(projectId);

        List<String> aimDeviceIdList = projectDeviceDeleteDTO.getDeviceIdList();
        if(ObjectUtil.isEmpty(aimDeviceIdList)){
            throw new CommonException("设备列表不能为空");
        }

        // 2.获取项目下所有设备ID
        List<String> deviceIdList = getProjectDeviceIdList(projectId);

        // 校验待删除的设备ID
        for (String deviceId : aimDeviceIdList) {
            if(!deviceIdList.contains(deviceId)){
                throw new CommonException("设备id不存在,id: " + deviceId);
            }
        }

        QueryWrapper<ProjectDevice> projectDeviceQueryWrapper = new QueryWrapper<>();
        projectDeviceQueryWrapper.lambda()
                .eq(ProjectDevice::getProjectId, projectId)
                .in(ObjectUtil.isNotEmpty(aimDeviceIdList), ProjectDevice::getDeviceId, aimDeviceIdList);

        // 执行删除
        return this.remove(projectDeviceQueryWrapper);
    }

    @Override
    public ProjectDeviceListVO getProjectDeviceList(ProjectDeviceSearchDTO projectDeviceSearchDTO) {
        ProjectDeviceListVO projectDeviceListVO = new ProjectDeviceListVO();

        // 1.项目ID校验
        String projectId = projectDeviceSearchDTO.getProjectId();
        ProjectUser projectUser = projectUserService.getProjectUserByProjectId(projectId);

        // 2.获取项目设备列表
        QueryWrapper<ProjectDevice> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ProjectDevice::getProjectId, projectId)
                .orderByDesc(ProjectDevice::getCreateTime);
        List<ProjectDevice> projectDeviceList = this.list(queryWrapper);

        List<ProjectDeviceInfoVO> deviceInfoVOList = new ArrayList<>();
        for(ProjectDevice projectDevice : projectDeviceList){
            // todo:调用device接口，根据deviceId获取设备信息
            DeviceInfoVO deviceInfoVO = deviceApi.getDeviceInfoById(projectDevice.getDeviceId());
            ProjectDeviceInfoVO projectDeviceInfoVO = BeanUtil.copyProperties(deviceInfoVO, ProjectDeviceInfoVO.class);

            projectDeviceInfoVO.setProjectId(projectId);
            projectDeviceInfoVO.setRole(projectUser.getRole());
            projectDeviceInfoVO.setDeviceId(projectDevice.getDeviceId());

            deviceInfoVOList.add(projectDeviceInfoVO);
        }
        projectDeviceListVO.setDevices(deviceInfoVOList);

        return projectDeviceListVO;
    }

    @Override
    public ProjectDevice queryEntity(String id) {
        ProjectDevice projectDevice = this.getById(id);
        if(ObjectUtil.isEmpty(projectDevice)) {
            throw new CommonException("APP项目设备不存在，id值为：{}", id);
        }
        return projectDevice;
    }
}
